package com.foxit.pdf2html5.common;

import java.awt.Toolkit;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.util.HashMap;
import java.util.Map;
import java.util.Timer;
import java.util.TimerTask;

import org.apache.commons.httpclient.HttpClient;
import org.apache.commons.httpclient.HttpStatus;
import org.apache.commons.httpclient.methods.InputStreamRequestEntity;
import org.apache.commons.httpclient.methods.PostMethod;
import org.apache.commons.httpclient.methods.RequestEntity;
import org.apache.commons.httpclient.params.HttpConnectionManagerParams;
import org.apache.commons.io.FileUtils;
import org.apache.log4j.Logger;
import org.json.JSONObject;

import com.foxit.conver2bin.task.ConversionEntrance;
import com.foxit.pdf2html5.common.utils.Base64;
import com.foxit.pdf2html5.common.utils.FXStringUtils;
import com.foxit.pdf2html5.common.utils.GetBean;
import com.foxit.pdf2html5.common.utils.TFSFileUntil;
import com.foxit.pdf2html5.tbschedule.task.ConversionHistoryInfo;
import com.foxit.pdf2html5.web.common.Config;
import com.google.code.morphia.Datastore;
import com.google.code.morphia.mapping.Mapper;
import com.google.gson.Gson;
import com.sun.jna.StringArray;


public class TaskStore {

	private static final Logger log = Logger.getLogger(TaskStore.class);
	private String conversionType = "convert2bin";
	private String cronType;
	private String tbschedulePatch = "http://192.201.108.61:8080/tbschedule/task/receive";
	private String excepireTime_minute = "30";
	private int task_restart_time_minute = 15;
	private int restarts_maximum_number = 20;
	
	private boolean isRetryTaskTimerStarted = false;
	
	Timer timer = new Timer();
	Toolkit toolkit;
	public int getRestarts_maximum_number() {
		return restarts_maximum_number;
	}


	public void setRestarts_maximum_number(int restarts_maximum_number) {
		this.restarts_maximum_number = restarts_maximum_number;
	}
	
	
	
	
	public boolean pushTask(String documentId,byte[] data,String fileName,String token)
			throws IOException
	{
		if(FXStringUtils.IsNullOrEmpty(conversionType)){
			log.error("Invalid conversion type.");
			return false;
		}
		if(FXStringUtils.IsNullOrEmpty(tbschedulePatch)){
			log.error("Invalid url of task receiving service.");
			return false;
		}
		
		int taskQueueMaxSize = Config.DEFAULT_TASK_QUEUE_MAX_SIZE;
		
		PostMethod postMethod = null;
		ByteArrayOutputStream swapStream = new ByteArrayOutputStream();  
//	    byte[] buff = new byte[1024];  
//	    int rc = 0;  
//	    while ((rc = inStream.read(buff, 0, 100)) > 0) {  
//	       swapStream.write(buff, 0, rc);  
//	    }  
//	    byte[] data = swapStream.toByteArray();
		//data = Base64.encode(data);
		HttpClient httpClient = new HttpClient();
		HttpConnectionManagerParams managerParams = httpClient.getHttpConnectionManager().getParams();
		managerParams.setConnectionTimeout(30000);
		managerParams.setSoTimeout(120000);
		postMethod = new PostMethod(tbschedulePatch);
		postMethod.addRequestHeader("Content-Type", "application/json");
		TaskBean taskBean = new TaskBean();
		taskBean.setType(conversionType);
		HashMap<String,Object> parameterJson = new HashMap<String, Object>();
		Gson gson = new Gson();
		parameterJson.put("documentId", documentId);
		//parameterJson.put("data", data);
		parameterJson.put("token",token);
		parameterJson.put("fileName", fileName);
		Map<String, String> parameters = new HashMap<String, String>();
		//base64 
		parameters.put("parameters", Base64.encode(gson.toJson(parameterJson)));
		
		taskBean.setParameters(parameters);
		String tempStr = gson.toJson(taskBean);
		String[] str = { Base64.encode(gson.toJson(parameterJson))};
		
		System.out.println(gson.toJson(parameterJson));
		//ConversionEntrance.main(str);	
		InputStream in = new ByteArrayInputStream(tempStr.getBytes());
		RequestEntity requestEntity = new InputStreamRequestEntity(in, "text/html;charset=UTF-8");
		postMethod.setRequestEntity(requestEntity);
		try {
			int statusCode = httpClient.executeMethod(postMethod);
			if (statusCode != HttpStatus.SC_OK) {
				log.error("Tbschedule receives the task failed.");
				return false;
			}else{
				try{
					String taksReponse = postMethod.getResponseBodyAsString();
					JSONObject jsonObject = null;
					int ret = 1;
					if(!FXStringUtils.IsNullOrEmpty(taksReponse)){
						jsonObject = new JSONObject(taksReponse);
						ret = jsonObject.getInt("ret");
					}
					if (jsonObject == null || ret != 0) {
						log.warn("Push task to tbschedule failed, reponse:"
								+ taksReponse);
						return false;
					}
				}
				catch(Exception ex){
					log.error(ex);
					return false;
				}	
			}
			return true;
		} catch (Exception e) {
			log.error(e);
			return false;
		} finally {
			if (postMethod != null) {
				postMethod.releaseConnection();
			}
		}
	}
	
	
	public void getTaskStatus(String docId){
		MyTask myTask = new MyTask(docId);
		timer.schedule(myTask, 1000, 2000);
	}
	
	public class MyTask extends TimerTask{

		private String docId = "";
		private int status = 0;
		
		
		public MyTask(String docId){
			this.docId = docId;
		}
		
		
		public int getStatus() {
			return status;
		}

		@Override
		public void run() {
			int numWarningBeeps = 3;
			if (numWarningBeeps > 0) {
			    toolkit.beep();
                System.out.println("Beep!");
				Datastore datastore = GetBean.getDatastore();
				ConversionHistoryInfo taskInfo = datastore.createQuery(ConversionHistoryInfo.class).field(Mapper.ID_KEY).equal(Base64.encode(this.docId)).get();
				if(taskInfo != null){
					status = taskInfo.getConversionStatus();
					if(status == 4 ){
						try {
								int ch = System.in.read();
								if(ch-'c'==0){
									timer.cancel();
									InputStream inStream = TFSFileUntil.readerContent(Config.FOXIT_EDITOR_CACHE_URL_KEY + docId + ".zip");
									if(inStream != null){
										FileUtils.copyInputStreamToFile(inStream, new File(Config.TEMP_FILE_PATH_KEY));
									}
								}
						} catch (IOException e) {
							e.printStackTrace();
						}
					}
				}
			   numWarningBeeps--;
			}else{
				toolkit.beep(); 
                System.out.println("Time's up!");
                System.exit(0); 
			}
		}
	}

}
